package org.metasketch.editor.diagrams;

import java.util.List;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToolBar;

import org.metasketch.editor.Project;
import org.metasketch.editor.project.CommonProject;
import org.metasketch.editor.timeline.SnapshotManager;
import org.metasketch.editor.toolbox.DiagramTypeManager;
import org.metasketch.editor.toolbox.IDiagramType;
import org.metasketch.editor.toolbox.SimpleToolBaseDiagramType;
import org.metasketch.editor.toolbox.ToolboxViewer;
import org.metasketch.editor.toolbox.advanced.ModelViewer;
import org.metasketch.graphics.Diagram;
import org.metasketch.javafx.graphics.DiagramView;
import org.metasketch.javafx.graphics.IDiagramChangeListener;
import org.metasketch.javafx.graphics.JFXDiagram;

public class DiagramManager implements IDiagramChangeListener,
		ChangeListener<Toggle> {

	protected DiagramTypeManager diagramTypeManager;

	protected DiagramView diagramViewer;

	protected ToolboxViewer toolboxViewer;

	protected ModelViewer modelViewer;

	protected CommonProject project;

	// String diagramId;

	private ToolBar tools;

	private SimpleToolBaseDiagramType simple;

	// private String toolId;

	public DiagramManager(DiagramTypeManager diagramTypeManager, Project project) {
		this.project = (CommonProject) project;
		this.diagramTypeManager = diagramTypeManager;

	}

	public List<String> getNames() {
		return diagramTypeManager.getNames();
	}

	public void setDiagramViewer(DiagramView viewer) {
		this.diagramViewer = viewer;
		diagramViewer.setListener(this);
	}

	public void setToolboxViewer(ToolboxViewer toolbox) {
		toolboxViewer = toolbox;
	}

	public ModelViewer getModelViewer() {
		return modelViewer;
	}

	public void setModelViewer(ModelViewer modelViewer) {
		this.modelViewer = modelViewer;
		// diagramTypeManager.set
	}

	public void createNewDiagram(String name) {

		// create diagram and set it on the project
		Diagram diagram = diagramTypeManager.createDiagram(name);
		project.addDiagram(diagram);

		// create a javafx diagram node and add it to the diagram viewer
		createGraphicalDiagram(diagram);

		setActiveDiagram(diagram);

		SnapshotManager.takeSnapshot();

	}

	protected void createGraphicalDiagram(Diagram diagram) {
		IDiagramType diagramType = diagramTypeManager.getDiagramType(diagram
				.getType());
		if (diagramType == null)
			return;

		Object graphicalDiagram = null;
		try {
			graphicalDiagram = diagramType.createGraphicalDiagram(diagram,
					project);
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		diagramViewer.addDiagram((JFXDiagram) graphicalDiagram);

	}

	public void setActiveDiagram(Diagram diagram) {

		if (simple != null) {
			simple.getGroup().selectedToggleProperty().removeListener(this);
		}

		SnapshotManager.setCurrentDiagramId(diagram.getId());

		IDiagramType diagramType = diagramTypeManager.getDiagramType(diagram
				.getType());

		if (diagramType == null)
			return;

		tools = diagramType.getToolbar();

		if (diagramType instanceof SimpleToolBaseDiagramType) {

			simple = (SimpleToolBaseDiagramType) diagramType;
			simple.getGroup().selectedToggleProperty().addListener(this);

			if (SnapshotManager.getCurrentToolId() != null) {
				ObservableList<Toggle> toggles = simple.getGroup().getToggles();
				for (Toggle toggle : toggles) {
					if (toggle instanceof ToggleButton) {
						String toggleId = (String) ((ToggleButton) toggle)
								.getUserData();
						if (toggleId != null
								&& toggleId.equals(SnapshotManager
										.getCurrentToolId())) {
							simple.getGroup().selectToggle(toggle);
							break;
						}
					}
				}
			}

		}

		toolboxViewer.setToolbox(tools);
		diagramType.setDragSource(modelViewer);

		diagramViewer.showDiagram(diagram);

	}

	@Override
	public void diagramSelectionChanged(Diagram diagram) {
		setActiveDiagram(diagram);

	}

	public void setProject(CommonProject project) throws Throwable {

		diagramViewer.clear();

		this.project = project;

		if (project != null) {
			List<Diagram> diagrams = project.getDiagrams().getDiagrams();
			for (Diagram diagram : diagrams) {
				createGraphicalDiagram(diagram);
			}

			Diagram activeDiagram = null;

			if (diagrams.size() > 0) {
				for (Diagram diagram : diagrams) {
					if (SnapshotManager.getCurrentDiagramId() != null
							&& SnapshotManager.getCurrentDiagramId().equals(
									diagram.getId())) {
						activeDiagram = diagram;
						break;
					}
				}
				// Diagram lastDiagram = diagrams.get(diagrams.size() - 1);

			}

			if (activeDiagram != null) {
				setActiveDiagram(activeDiagram);
			} else if (diagrams.size() > 0) {
				setActiveDiagram(diagrams.get(diagrams.size() - 1));
			}

		}
	}

	@Override
	public void changed(ObservableValue<? extends Toggle> arg0, Toggle arg1,
			Toggle arg2) {

		if (arg2 instanceof ToggleButton) {
			SnapshotManager.setCurrentToolId((String) ((ToggleButton) arg2)
					.getUserData());
			System.out
					.println("tool id: " + SnapshotManager.getCurrentToolId());
		}

	}

}
